<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Canvas</title>
    <style></style>
  </head>
  <body>
    <div class="container">
      <canvas id="demo"></canvas>
    </div>

    <script>
      ;(function () {
        const $canvas = document.querySelector('#demo')
        $canvas.width = 600
        $canvas.height = 600
        $canvas.style.border = '1px solid #cccccc'

        const context = $canvas.getContext('2d')

        // 绘制扇区
        const sectionData = [
          {
            value: 0.2,
            color: 'red',
            title: '项目1',
          },
          {
            value: 0.3,
            color: 'yellow',
            title: '项目2',
          },
          {
            value: 0.4,
            color: 'blue',
            title: '项目3',
          },
          {
            value: 0.1,
            color: 'green',
            title: '项目4',
          },
        ]

        function drawSection(originX, originY, originR) {
          // 参数：初始饼图的坐标，半径
          // 从竖直上方开始绘制 -90度
          let currentDeg = -90

          return function (color, value, title) {
            context.beginPath()
            context.moveTo(originX, originY)

            // 需要转动的角度
            let angel = value * 360

            // 需要转动 到 的角度=当前角度 + 需要转动的角度
            let turnToAngel = currentDeg + value * 360

            // 绘制圆弧
            // true 逆时针，false 顺时针
            context.arc(
              originX,
              originY,
              originR,
              (Math.PI / 180) * currentDeg,
              (Math.PI / 180) * turnToAngel,
              false
            )
            // 闭合路径
            context.closePath()
            context.stroke()
            context.fillStyle = color
            context.fill()

            // 绘制文字
            context.beginPath()
            context.font = '14px sans-serif'

            // 文字需要转动到的角度（扇形的一半）
            let textAngel = currentDeg + (value * 360) / 2
            let x =
              originX + Math.cos(textAngel * (Math.PI / 180)) * (originR + 20)

            let y =
              originY + Math.sin(textAngel * (Math.PI / 180)) * (originR + 20)

            if (textAngel > 90 && textAngel < 270) {
              context.textAlign = 'end'
            }

            context.fillText(title, x, y)

            currentDeg = turnToAngel
          }
        }

        const fn = drawSection(300, 300, 100)
        sectionData.forEach((item) => {
          fn(item.color, item.value, item.title)
        })
      })()
    </script>
  </body>
</html>
